package com.zlb.envmodify.util;

import com.zlb.envmodify.service.EnvModifyServiceFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author zhulb
 * @description
 * @create 2022-09-14
 */
public class EnvModifyAgentUtil {

    static Logger logger = Logger.getLogger(EnvModifyAgentUtil.class.getName());

    private static Map<Object, Object> config = new HashMap<>();

    private static Map<String, String> ignore = new HashMap<>();

    static {
        ignore.put("systemEnvironment", null);
        ignore.put("systemProperties", null);
    }

    public static void showResource(Object yamlObj) {
//        try {
//            Class<?> yamlClass = Class.forName("org.springframework.beans.factory.config.YamlProcessor");
//            Field field = yamlClass.getDeclaredField("resources");
//            field.setAccessible(true);
//            Object[] res = (Object[]) field.get(yamlObj);
//            System.out.println(res[0].toString());
//        } catch (Exception e) {
//            e.printStackTrace();
//            System.exit(99);
//        }
    }

    public static void showNacosParams(String dataId, String group, String fileExtension) {
        System.out.println("加载nacos配置:" + dataId + "," + group + "," + fileExtension);
    }

    public static void showYamlParams(Map<String, Object> source) {
        System.out.println(source);
    }

    public static void saveConfig(Object key, Object value) {
        config.put(key, value);
    }

    public static void showConfig() {
        StringBuilder configStr = new StringBuilder();
        config.entrySet().stream().sorted(new Comparator<Map.Entry<Object, Object>>() {
            @Override
            public int compare(Map.Entry<Object, Object> o1, Map.Entry<Object, Object> o2) {
                return o1.getKey().toString().compareTo(o2.getKey().toString());
            }
        }).forEach(q -> {
            if (q.getKey().toString().startsWith("spring.cloud.nacos") || q.getKey().toString().startsWith("spring.profiles")) {
                configStr.append("# " + EnvModifyServiceFactory.getSigleton().getConfigEnvPrefix() + "." + System.getenv("SYSTEM_CODE") + "." + q.getKey() + "=" + q.getValue() + "\n");
            } else {
                configStr.append(EnvModifyServiceFactory.getSigleton().getConfigEnvPrefix() + "." + System.getenv("SYSTEM_CODE") + "." + q.getKey() + "=" + q.getValue() + "\n");
            }
        });
    }

    public static Map replace(String name, Map oldMap) {
        Map newMap = new HashMap();
        Object[] arr = oldMap.keySet().toArray();
        for (int i = 0; i < arr.length; i++) {
            if (System.getProperty((String) arr[i]) != null && !System.getProperty((String) arr[i]).equals(oldMap.get(arr[i]))) {
                newMap.put(arr[i], System.getProperty((String) arr[i]));
                oldMap.put(arr[i], System.getProperty((String) arr[i]));
                if (!ignore.containsKey(name)) {
                    System.out.println("config.zlb.env." + EnvModifyServiceFactory.getSigleton().getSystemCode() + "." + arr[i] + "=" + System.getProperty((String) arr[i]) + " # " + name);
                }
            } else {
                newMap.put(arr[i], oldMap.get(arr[i]));
                if (!ignore.containsKey(name)) {
                    System.out.println("config.zlb.env." + EnvModifyServiceFactory.getSigleton().getSystemCode() + "." + arr[i] + "=" + oldMap.get(arr[i]) + " # " + name);
                }
            }
            EnvModifyAgentUtil.saveConfig(arr[i], newMap.get(arr[i]));
        }
        return oldMap;
    }

    public static void echoRequestParams(Object request) {
        try {
            Method getParameterMap = null;
            if (request == null || (getParameterMap = getMethod(request)) == null) {
                return;
            }
            getParameterMap.setAccessible(true);
            Map<String, String[]> paramsMap = (Map<String, String[]>) getParameterMap.invoke(request);
            if (paramsMap != null) {
                paramsMap.entrySet().stream().forEach(q -> {
                    if (paramsMap.get(q) != null && paramsMap.get(q).length > 1) {
                        System.out.println(q + "=" + paramsMap.get(q)[0]);
                    } else {
                        System.out.println(q + "=");
                    }
                });
            }
            System.out.println(paramsMap);

            Method getRequestURI = request.getClass().getDeclaredMethod("getRequestURI");
            getRequestURI.setAccessible(true);
            String url = (String) getRequestURI.invoke(request);
            logger.info(url);
        } catch (Exception e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }
    }

    private static Method getMethod(Object request) {
        try {
            return request.getClass().getDeclaredMethod("getParameterMap");
        } catch (Exception e) {
            logger.log(Level.WARNING, e, null);
            return null;
        }
    }


}
